#include "dcmimportwidget.h"
#include "ui_dcmimportwidget.h"
#include "../../ImageAcquisitor/ImageAcquisitor/global.h"

#include "scandcmfilethread.h"
#include "importdcmfilethread.h"
#include "importstudymodel.h"

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSettings>
#include <QFileDialog>
#include <QSettings>
#include <QDir>
#include <QFileInfo>
#include <QJsonObject>

#define STUDY_IMPORT_FILE "STUDYIMPORTFILE"
#define STUDY_IMPORT_DIR "STUDYIMPORTDIR"

DcmImportWidget::DcmImportWidget(QWidget *parent) :
    importedStudies(0),
    importedImages(0),
    m_proc(0),
    m_userData(0),
    m(new ImportStudyModel(this)),
    t(new ImportDcmFileThread(this)),
    QWidget(parent),
    ui(new Ui::DcmImportWidget)
{
    ui->setupUi(this);
    initNetwork();
    ui->studyView->setModel(m);
    connect(ui->clearButton, SIGNAL(clicked()), m, SLOT(clear()));
    connect(t, SIGNAL(finished()), this, SLOT(onImportFinished()));
    connect(t, SIGNAL(resultReady(StudyRecord*)), this, SLOT(onImportResultReady(StudyRecord*)));
    connect(t, SIGNAL(resultReady(StudyRecord*)), m, SLOT(updateStudyStatus(StudyRecord*)));
    connect(t, SIGNAL(fileTransferred()), this, SLOT(onImportFileTransferred()));
}

DcmImportWidget::~DcmImportWidget()
{
    delete ui;
}

void DcmImportWidget::initNetwork()
{
    QSettings s(LOCAL_NETWORK_CONFIG, QSettings::IniFormat);
    s.setIniCodec(QSETTINGS_CODEC_NAME);

    if (!QSqlDatabase::database().isOpen()) {
        QString type = s.value(NETWORK_DBMS_TYPE).toString();
        QSqlDatabase d = QSqlDatabase::addDatabase(type);
        if (d.isValid()) {
            d.setHostName(s.value(NETWORK_DBMS_HOST).toString());
            d.setPort(s.value(NETWORK_DBMS_PORT).toInt());
            d.setDatabaseName(s.value(NETWORK_DBMS_NAME).toString());
            d.setUserName(s.value(NETWORK_DBMS_USER).toString());
            d.setPassword(s.value(NETWORK_DBMS_PWD).toString());
        }
    }
}

void DcmImportWidget::on_fileButton_clicked()
{
    QSettings s;
    QString file = s.value(STUDY_IMPORT_FILE).toString();
    if (file.isEmpty()) file = ".";
    QStringList files = QFileDialog::getOpenFileNames(this, tr("Import Study"),
                                                      file, tr("DICOM Files(*.dcm);;All Files(*)"));
    if (files.size()) {
        s.setValue(STUDY_IMPORT_FILE, files.first());
        scanFiles(files);
    }
}

void DcmImportWidget::on_folderButton_clicked()
{
    QSettings s;
    QString dir = s.value(STUDY_IMPORT_DIR).toString();
    if (dir.isEmpty()) dir = ".";
    dir = QFileDialog::getExistingDirectory(this, tr("Import Study"), dir);
    if (!dir.isEmpty()) {
        s.setValue(STUDY_IMPORT_DIR, dir);
        QStringList files;
        scanDirHelpper(files, dir);
        scanFiles(files);
    }
}

void DcmImportWidget::on_importButton_clicked(bool checked)
{
    if (checked) {
        ui->progressBar->setValue(0);
        ui->progressBar->setMaximum(m->getImageCnt());
        importedStudies = 0;
        importedImages = 0;
        t->setStudyList(m->getStudyList());
        t->start();
        ui->importButton->setText(tr("Abort"));
    } else {
        t->setAbort(true);
        t->wait();
    }
}

void DcmImportWidget::onImportFinished()
{
    ui->progressBar->setValue(ui->progressBar->maximum());
    ui->importButton->setChecked(false);
    ui->importButton->setText(tr("Import"));
    if (m_proc) {
        QJsonObject json;
        json["action"] = "ImportEnd";
        m_proc(json, m_userData);
    }
}

void DcmImportWidget::onScanFinished()
{
    ui->progressBar->setValue(ui->progressBar->maximum());
    ui->fileButton->setEnabled(true);
    ui->folderButton->setEnabled(true);
    ui->importButton->setEnabled(m->getStudyCnt());
    ui->clearButton->setEnabled(true);
}

void DcmImportWidget::onImportResultReady(StudyRecord *study)
{
    if (study) {
        importedStudies++;
        foreach (ImageRecord *r, study->imageList) {
            if (r->ok) importedImages++;
        }
        ui->impStudyCnt->setText(QString::number(importedStudies));
        ui->impImageCnt->setText(QString::number(importedImages));
    }
}

void DcmImportWidget::onImportFileTransferred()
{
    int v = ui->progressBar->value();
    ui->progressBar->setValue(v+1);
}

void DcmImportWidget::onScanResultReady()
{
    ui->progressBar->setValue(ui->progressBar->value()+1);
    ui->scanStudyCnt->setText(QString::number(m->getStudyCnt()));
    ui->scanImageCnt->setText(QString::number(m->getImageCnt()));
}

void DcmImportWidget::scanFiles(const QStringList &files)
{
    m->clear();
    if (files.isEmpty()) return;
    ui->progressBar->setValue(0);
    ui->progressBar->setMaximum(files.size());
    ui->fileButton->setEnabled(false);
    ui->folderButton->setEnabled(false);
    ui->importButton->setEnabled(false);
    ui->clearButton->setEnabled(false);
    ui->scanImageCnt->setText(QString::number(0));
    ui->scanStudyCnt->setText(QString::number(0));
    ui->impStudyCnt->setText(QString::number(0));
    ui->impImageCnt->setText(QString::number(0));
    ScanDcmFileThread *t = new ScanDcmFileThread;
    connect(t, SIGNAL(finished()), t, SLOT(deleteLater()));
    connect(t, SIGNAL(finished()), this, SLOT(onScanFinished()));
    connect(t, SIGNAL(resultReady(StudyRecord*)), m, SLOT(appendStudy(StudyRecord*)));
    connect(t, SIGNAL(resultReady(StudyRecord*)), this, SLOT(onScanResultReady()));
    t->setFiles(files);
    t->start();
}

void DcmImportWidget::scanDirHelpper(QStringList &files, const QString &dir)
{
    QDir qdir(dir);

    QFileInfoList infoList = qdir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
    foreach (const QFileInfo &info, infoList) {
        if (info.isFile())
            files.append(info.filePath());
        else if (info.isDir())
            scanDirHelpper(files, info.filePath());
    }
}
